package com.baijiayun.live.ui.speakerlist.item;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.res.Configuration;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

import com.baijiayun.live.ui.activity.LiveRoomRouterListener;
import com.baijiayun.live.ui.pptpanel.MyPadPPTView;
import com.baijiayun.liveuibase.utils.RxUtils;
import com.baijiayun.livecore.alilog.AliYunLogHelper;
import com.baijiayun.livecore.context.LPConstants;
import com.baijiayun.livecore.ppt.PPTView;
import com.baijiayun.livecore.utils.LPLogger;

import java.lang.ref.WeakReference;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.disposables.Disposable;

import static com.baijiayun.live.ui.speakerlist.item.SwitchableStatus.MainVideo;
import static com.baijiayun.live.ui.speakerlist.item.SwitchableStatus.MaxScreen;
import static com.baijiayun.live.ui.speakerlist.item.SwitchableStatus.SpeakList;

/**
 * Created by Shubo on 2019-07-30.
 */
public abstract class BaseSwitchItem implements Switchable {

    protected SwitchableStatus status = SwitchableStatus.None;
    //是否在全屏，因为要还原状态所以全屏不包括在status里面
    private boolean isInFullScreen = false;
    protected LiveRoomRouterListener routerListener;

    public BaseSwitchItem(LiveRoomRouterListener listener) {
        this.routerListener = listener;
    }

    @Override
    public int getPositionInParent() {
        View view = getView();
        ViewParent viewParent = getView().getParent();
        if (viewParent == null)
            return -1;
        return ((ViewGroup) viewParent).indexOfChild(view);
    }

    @Override
    public SwitchableStatus getSwitchableStatus() {
        return status;
    }

    @Override
    public void setSwitchableStatus(SwitchableStatus status) {
        this.status = status;
    }

    @Override
    public void switchToMaxScreen() {
        removeSwitchableFromParent(this);
        routerListener.switchToMaxScreen(this);
        status = MaxScreen;
    }

    @Override
    public void switchToSpeakList() {
        removeSwitchableFromParent(this);
        routerListener.switchToSpeakList(this);
        status = SpeakList;
    }

    @Override
    public void switchToFullScreen(boolean isFullScreen) {
        removeSwitchableFromParent(this);
        routerListener.switchToFullScreen(this, isFullScreen);
        this.isInFullScreen = isFullScreen;
    }

    @Override
    public void switchToMainScreen() {
        removeSwitchableFromParent(this);
        routerListener.switchToMainScreen(this);
        status = MainVideo;
    }

    @Override
    public boolean isInFullScreen() {
        return isInFullScreen;
    }


    protected void removeSwitchableFromParent(Switchable switchable) {
        View view = switchable.getView();
        if (view == null) return;
        ViewParent viewParent = view.getParent();
        if (viewParent == null) return;
        ((ViewGroup) viewParent).removeView(view);
    }

    @SuppressLint("ClickableViewAccessibility")
    protected void registerClickEvent(View view) {
        GestureDetector gestureDetector = new GestureDetector(view.getContext(), new ClickGestureDetector(this));
        view.setOnTouchListener((v, event) -> {
            gestureDetector.onTouchEvent(event);
            return true;
        });
    }

    public abstract void showOptionDialog();

    protected boolean canSwitchPPTAndMainVideo() {
        //非纯视频模板、视频墙且不是画廊布局则可切换ppt和白板
        if (routerListener.getLiveRoom().getTemplateType() == LPConstants.TemplateType.LIVE_WALL) {
            return routerListener.getLiveRoom().getCurrentRoomLayout() != LPConstants.RoomLayoutMode.GALLERY;
        }
        return routerListener.getLiveRoom().getTemplateType() != LPConstants.TemplateType.VIDEO;
    }

    @Override
    public void switchPPTVideoSync() {
        switchPPTVideoWithoutSync(true);
    }

    @Override
    public void switchPPTVideoWithoutSync(boolean immediately) {
        final Switchable maxScreenItem = routerListener.getMaxScreenItem();
        if (maxScreenItem == null) {
            AliYunLogHelper.getInstance().addErrorLog("切换报错出错,ppt:" + routerListener.getPPTView()
                    + "---main:" + routerListener.getMainScreenItem());
            return;
        }
        //支持切换到mainScreen
        //可能有一次切换或两次切换
        final PPTView pptView = routerListener.getPPTView();
        switch (getSwitchableType()) {
            case MainItem:
                //main切到max。如果speakItem在maxScreen发生两次切换
                if (pptView instanceof Switchable) {
                    if (maxScreenItem.getSwitchableType() == SwitchableType.PPT) {
                        if (!maxScreenItem.isInFullScreen() || immediately) {
                            if (maxScreenItem.isInFullScreen()) {
                                //立即切换且在全屏
                                maxScreenItem.switchToFullScreen(false);
                            }
                            maxScreenItem.switchToMainScreen();
                        } else {
                            maxScreenItem.setSwitchableStatus(MainVideo);
                        }
                    } else if (maxScreenItem.getSwitchableType() == SwitchableType.SpeakItem) {
                        final Switchable switchable = (Switchable) pptView;
                        if (!switchable.isInFullScreen() || immediately) {
                            if (switchable.isInFullScreen()) {
                                //立即切换且在全屏
                                switchable.switchToFullScreen(false);
                            }
                            switchable.switchToMainScreen();
                        } else {
                            switchable.setSwitchableStatus(MainVideo);
                        }
                        if (!maxScreenItem.isInFullScreen() || immediately) {
                            if (maxScreenItem.isInFullScreen()) {
                                //立即切换且在全屏
                                maxScreenItem.switchToFullScreen(false);
                            }
                            maxScreenItem.switchToSpeakList();
                        } else {
                            maxScreenItem.setSwitchableStatus(SpeakList);
                        }
                    }
                }
                break;
            case SpeakItem:
                //从speak切到max。如果mainItem在maxScreen发生两次切换
                if (pptView instanceof Switchable) {
                    if (maxScreenItem.getSwitchableType() == SwitchableType.PPT) {
                        if (!maxScreenItem.isInFullScreen() || immediately) {
                            if (maxScreenItem.isInFullScreen()) {
                                //立即切换且在全屏
                                maxScreenItem.switchToFullScreen(false);
                            }
                            maxScreenItem.switchToSpeakList();
                        } else {
                            maxScreenItem.setSwitchableStatus(SpeakList);
                        }
                    } else if (maxScreenItem.getSwitchableType() == SwitchableType.MainItem) {
                        final Switchable switchable = (Switchable) pptView;
                        if (!switchable.isInFullScreen() || immediately) {
                            if (switchable.isInFullScreen()) {
                                //立即切换且在全屏
                                switchable.switchToFullScreen(false);
                            }
                            switchable.switchToSpeakList();
                        } else {
                            switchable.setSwitchableStatus(SpeakList);
                        }
                        if (!maxScreenItem.isInFullScreen() || immediately) {
                            if (maxScreenItem.isInFullScreen()) {
                                //立即切换且在全屏
                                maxScreenItem.switchToFullScreen(false);
                            }
                            maxScreenItem.switchToMainScreen();
                        } else {
                            maxScreenItem.setSwitchableStatus(MainVideo);
                        }
                    } else if (maxScreenItem.getSwitchableType() == SwitchableType.SpeakItem) {
                        if (!maxScreenItem.isInFullScreen() || immediately) {
                            if (maxScreenItem.isInFullScreen()) {
                                //立即切换且在全屏
                                maxScreenItem.switchToFullScreen(false);
                            }
                            maxScreenItem.switchToSpeakList();
                        } else {
                            maxScreenItem.setSwitchableStatus(SpeakList);
                        }
                    }
                }
                break;
            //辅助摄像头type是PPT
            case PPT:
                if (maxScreenItem.getSwitchableType() == SwitchableType.SpeakItem) {
                    if (!maxScreenItem.isInFullScreen() || immediately) {
                        if (maxScreenItem.isInFullScreen()) {
                            //立即切换且在全屏
                            maxScreenItem.switchToFullScreen(false);
                        }
                        maxScreenItem.switchToSpeakList();
                    } else {
                        maxScreenItem.setSwitchableStatus(SpeakList);
                    }
                } else if (maxScreenItem.getSwitchableType() == SwitchableType.MainItem) {
                    if (!maxScreenItem.isInFullScreen() || immediately) {
                        if (maxScreenItem.isInFullScreen()) {
                            //立即切换且在全屏
                            maxScreenItem.switchToFullScreen(false);
                        }
                        maxScreenItem.switchToMainScreen();
                    } else {
                        maxScreenItem.setSwitchableStatus(MainVideo);
                    }
                } else if (maxScreenItem.getSwitchableType() == SwitchableType.PPT) {
                    //辅助摄像头关闭ppt
                    if (maxScreenItem instanceof MyPadPPTView) {
                        MyPadPPTView myPadPPTView = (MyPadPPTView) maxScreenItem;
                        myPadPPTView.closePPTbyExtCamera();
                    }
                }
                break;
            default:
                break;
        }
        if (!isInFullScreen || immediately) {
            if (isInFullScreen) {
                //立即切换且在全屏
                switchToFullScreen(false);
            }
            switchToMaxScreen();
        } else {
            setSwitchableStatus(MaxScreen);
        }
    }

    @Override
    public void syncPPTExtCamera(Switchable closeItem) {
        if (closeItem.isInFullScreen()) {
            switch (closeItem.getSwitchableStatus()) {
                case MainVideo:
                    switchToMainScreen();
                    break;
                case MaxScreen:
                    switchToMaxScreen();
                    break;
                case SpeakList:
                    switchToSpeakList();
                    break;
            }
            switchToFullScreen(true);
        } else {
            switch (closeItem.getSwitchableStatus()) {
                case MainVideo:
                    switchToMainScreen();
                    break;
                case MaxScreen:
                    switchToMaxScreen();
                    break;
                case SpeakList:
                    switchToSpeakList();
                    break;
            }
        }
    }

    protected boolean enableClearScreen() {
        return false;
    }

    @Override
    public boolean isPlaceholderItem() {
        return false;
    }

    @Override
    public void replaceVideoSync(Switchable switchable) {
        if (switchable == null) {
            return;
        }
        if (switchable == this) {
            switch (switchable.getSwitchableStatus()) {
                case MainVideo:
                    switchToMainScreen();
                    break;
                case MaxScreen:
                    switchToMaxScreen();
                    break;
                case SpeakList:
                    switchToSpeakList();
                    break;
                default:
                    break;
            }
            return;
        }
        if (isPlaceholderItem() || switchable.isPlaceholderItem()) {
            handlePlaceholderItemSync(switchable);
            return;
        }
        SwitchableStatus currentStatus = status;
        switch (switchable.getSwitchableStatus()) {
            case MainVideo:
                switchToMainScreen();
                break;
            case MaxScreen:
                switchToMaxScreen();
                break;
            case SpeakList:
                switchToSpeakList();
                break;
            default:
                break;
        }
        switch (currentStatus) {
            case MainVideo:
                switchable.switchToMainScreen();
                break;
            case SpeakList:
                switchable.switchToSpeakList();
                break;
            case MaxScreen:
                switchable.switchToMaxScreen();
                break;
            default:
                break;
        }
        if (switchable.isInFullScreen()) {
            switchable.switchToFullScreen(false);
            switchToFullScreen(true);
        }
        if (isInFullScreen()) {
            switchToFullScreen(false);
            switchable.switchToFullScreen(true);
        }
    }

    /**
     * 处理占位图问题,本身或者被替换的switchable是占位图
     *
     * @param switchable
     */
    private void handlePlaceholderItemSync(Switchable switchable) {
        //占位图替换主讲，主讲一定已经退出
        //要么是主讲替换占位图
        switch (switchable.getSwitchableStatus()) {
            case MainVideo:
                switchToMainScreen();
                break;
            case MaxScreen:
                switchToMaxScreen();
                break;
            case SpeakList:
                LPLogger.e("handlePlaceholderItemSync", "presenter switch2SpeakList");
                break;
            default:
                break;
        }
        //占位图替换主讲只走上面逻辑
        //主讲替换占位图还走下面逻辑
        if (isPlaceholderItem() || !switchable.isPlaceholderItem()) {
            return;
        }
        switchable.switchToMainScreen();
        final PPTView pptView = routerListener.getPPTView();
        if (pptView instanceof Switchable && getSwitchableStatus() == MaxScreen) {
            Switchable ppt = (Switchable) pptView;
            ppt.switchToMainScreen();
        }
    }

    private static class ClickGestureDetector extends GestureDetector.SimpleOnGestureListener {

        private WeakReference<BaseSwitchItem> baseSwitchItemWeakReference;

        ClickGestureDetector(BaseSwitchItem switchItem) {
            baseSwitchItemWeakReference = new WeakReference<>(switchItem);
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            BaseSwitchItem switchable = baseSwitchItemWeakReference.get();
            if (switchable == null) {
                RxUtils.dispose(subscriptionOfClickable);
                return false;
            }
            if (clickableCheck()) {
                return false;
            }
            if (switchable.getSwitchableStatus() != MaxScreen || switchable.isInFullScreen()) {
                switchable.showOptionDialog();
            }
            return true;
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            BaseSwitchItem switchable = baseSwitchItemWeakReference.get();
            if (switchable == null) {
                RxUtils.dispose(subscriptionOfClickable);
                return false;
            }
            if (clickableCheck()) {
                return false;
            }
            if (switchable.getSwitchableStatus() == MaxScreen || switchable.isInFullScreen) {
                return false;
            }
            if ((switchable instanceof Playable && ((Playable) switchable).isVideoStreaming()) || switchable.isPlaceholderItem()) {
                if (!switchable.canSwitchPPTAndMainVideo()) {
                    return super.onDoubleTap(e);
                }
                switchable.switchPPTVideoSync();
            }
            return super.onDoubleTap(e);
        }

        Disposable subscriptionOfClickable;

        private boolean clickableCheck() {
            if (subscriptionOfClickable != null && !subscriptionOfClickable.isDisposed()) {
                return true;
            }
            subscriptionOfClickable = Observable.timer(1, TimeUnit.SECONDS).subscribe(aLong -> RxUtils.dispose(subscriptionOfClickable));
            return false;
        }
    }
}
